iT邦幫忙

2024 iThome 鐵人賽

DAY 24
0
Modern Web

雙向奔赴的websocket與冰冷的react系列 第 24

[day24]React Router動態路由與導航

  • 分享至 

  • xImage
  •  

基本動態路由

動態路由是通過在 Route 的 path 中使用參數來實現的,例如 /user/:id,這裡的 :id 是一個動態參數,可以根據 URL 的變化來渲染不同的內容。

目標:
我們將實現一個用戶頁面,當用戶進入 /user/1 時顯示用戶 1 的資訊,進入 /user/2 時顯示用戶 2 的資訊。

開始

本次的檔案配置如下

src
 |
 |--Home.jsx
 |--User.jsx
 |--NotFound.jsx
 |--index.js
  • SubHome.jsx
import React from 'react';
import { Link } from 'react-router-dom';

function SubHome() {
  return (
    <div>
      <h2>這是首頁</h2>
      <ul>
        <li>
          <Link to="/user/1">查看用戶 1</Link>
        </li>
        <li>
          <Link to="/user/2">查看用戶 2</Link>
        </li>
        <li>
          <Link to="/user/3">查看用戶 3</Link>
        </li>
        <li>
          <Link to="/user">不給id</Link>
        </li>
      </ul>
    </div>
  );
}

export default SubHome;

這裡就一般的布置頁面

  • User.jsx
import React from 'react';
import { useParams } from 'react-router-dom';

function User() {
  // 使用 useParams 來獲取 URL 中的動態參數
  const { id } = useParams();

  return (
    <div>
      <h2>用戶資料</h2>
      <p>當前用戶 ID: {id}</p>
    </div>
  );
}

export default User;

  • 比較特別的useParams他能夠抓取url的動態參數

  • NotFound.jsx

import React from 'react';

function NotFound() {
  return (
    <div>
      <h2>404 - 頁面未找到</h2>
    </div>
  );
}

export default NotFound;

也是一般的布置

index.js

繼續擔當本次重點

import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './SubHome';
import User from './User';
import NotFound from './NotFound';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        {/* 動態路由,匹配 /user/後面的 id */}
        <Route path="/user/:id" element={<User />} />
        {/* 若路徑不匹配,顯示 404 頁面 */}
        <Route path="*" element={<NotFound />} />
      </Routes>
    </Router>
  );
}

const rootElement = document.getElementById('root');
const root = ReactDOM.createRoot(rootElement);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

在 index.js 中,我們設置動態路由和基本導航。當訪問 /user/:id 時,根據 URL 中的 id 動態渲染 User 組件。

實作說明

  • 動態路由:
    path="/user/:id":在這裡,:id 是一個動態參數,表示這個路由可以接受任何後綴為 /user/任意ID 的 URL,並將這個 id 作為參數傳遞給 User 組件。
    useParams Hook:在 User 組件中,使用 useParams Hook 來獲取 URL 中的 id 值,這樣我們可以根據 id 渲染不同的用戶資料。
  • 導航功能:
    在 Home 組件中,我們使用了 <Link> 元件來實現導航。每個鏈接指向不同的 /user/:id 路徑,這樣點擊不同的鏈接就能導航到不同的用戶頁面。
  • 404 頁面處理:
    使用 Route path="*" 來處理未匹配到的路徑,*表示匹配所有路徑,也就是「通配路徑」,當 URL 沒有對應的 Route 時,就會渲染 NotFound 組件,展示 404 錯誤。

小補充

在React Route中不像Vue Route有所謂的score導致的路徑優先權問題,基本上如果你有兩個path都是"/App",他會以最上面的為主例如

<Route path="/App" element={<App1 />}>
<Route path="/App" element={<App2 />}>

會以App1優先導出,那你可能會想如果path使用「通配路徑」*那不就必須放在最底下?在以前可能沒錯

不過在 React Router v6 中,路由的匹配是根據「路徑的具體性」來排序的,這意味著:

  • 更具體的路徑會優先匹配,例如 /about 會比 * 更具體,因為 * 是通配路徑。

  • path="*"會匹配所有剩餘的路徑,但它會自動被排在最後,即使你將它放在路由表的前面,React Router 仍會優先嘗試匹配具體路徑。

  • 如果App1的路徑回報404呢?App2可能渲染嗎?
    React Router 並不會根據組件內部的邏輯(如 App1 回報的 404 錯誤)來決定是否切換到其他路由。只要 path="/App" 與當前的 URL 匹配,它會始終渲染 App1。無論 App1 組件內部發生什麼錯誤或顯示了什麼,React Router 都不會切換到 App2。

所以請確保path的唯一性

今天結束了,近來颱風天各位小心唷


上一篇
[day23]React Router 基礎介紹與路由設定
下一篇
[day25]React Router 路由守衛與嵌套路由
系列文
雙向奔赴的websocket與冰冷的react30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言